package lion.framework.model.gen;

import java.io.IOException;
import java.util.List;

import org.apache.commons.io.IOUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import lion.dev.fun.Funs;
import lion.dev.lang.MapJ;
import lion.framework.core.db.DataSourceManager;

/**
 *
 * 根据PowerDesigner pdm文件批量生成Java类
 *
 * @author lion
 * @email hl_0074@sina.com
 * @date 2014年4月3日
 */
public class PDMGen {

	/**
	 * POJO
	 */
	public static void pojo(String pkg, String pdm) throws DocumentException {

		try {
			String template = IOUtils.toString(Model.class.getResourceAsStream("tmpl/pojo.tmpl"));
			defind("src", pkg, pdm, template, null);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void pojo(String base, String pkg, String pdm) throws DocumentException {

		try {
			String template = IOUtils.toString(Model.class.getResourceAsStream("tmpl/pojo.tmpl"));
			defind(base, pkg, pdm, template, null);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void rbm(String pkg, String pdm) throws DocumentException {
		rbm("src", pkg, pdm);
	}

	/**
	 * Rich Blook Mode
	 */
	public static void rbm(String base, String pkg, String pdm) throws DocumentException {

		// funs
		Funs fun = new Funs();
		fun.add("insertsql", (Object... args) -> {
			MapJ context = (MapJ) args[0];
			String[][] fields = context.getE("fields");
			StringBuilder sbu = new StringBuilder("insert into  \" + TABLE_NAME + \"(");
			StringBuilder sbu1 = new StringBuilder();
			StringBuilder sbu2 = new StringBuilder();
			boolean b = false;
			for (String[] f : fields) {
				if (f[0].equalsIgnoreCase("id")) {
					continue;
				}
				if (b) {
					sbu1.append(",");
					sbu2.append(",");
				}
				b = true;
				sbu1.append(f[0]);
				sbu2.append(":" + f[0]);
			}
			sbu.append(sbu1.toString() + ")values(" + sbu2.toString() + ")");
			return sbu.toString();
		});

		fun.add("updatesql", (Object... args) -> {
			MapJ context = (MapJ) args[0];
			String[][] fields = context.getE("fields");
			StringBuilder sbu = new StringBuilder("update \" + TABLE_NAME + \" set ");
			boolean b = false;
			for (String[] f : fields) {
				if (f[0].equalsIgnoreCase("id")) {
					continue;
				}
				if (b) {
					sbu.append(",");
				}
				b = true;
				sbu.append(f[0] + "=:" + f[0]);
			}
			sbu.append(" where id=:id");
			return sbu.toString();
		});

		try {
			String template = IOUtils.toString(Model.class.getResourceAsStream("tmpl/rbm.tmpl"));
			defind(base, pkg, pdm, template, fun);
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	@SuppressWarnings("unchecked")
	public static void defind(String base, String pkg, String pdm, String template, Funs funs)
			throws DocumentException {

		SAXReader reader = new SAXReader();
		Document doc = reader.read(pdm);

		List<Element> nodes = doc.selectNodes("//c:Tables/o:Table");

		for (Element element : nodes) {
			String className = pkg + "." + element.elementTextTrim("Code");
			List<Element> columnElements = element.selectNodes("c:Columns/o:Column");
			String[][] columns = new String[columnElements.size()][2];
			for (int i = 0; i < columns.length; i++) {
				Element elem = columnElements.get(i);
				columns[i][0] = elem.elementTextTrim("Code");
				columns[i][1] = DataSourceManager.getJavaTypeName(elem.elementTextTrim("DataType"));
			}
			Model.define(base, template, className, columns, funs);
		}
	}

}
